module encoder #(// expshare 1
    parameter ARR_Len = 16  ,
    parameter Eshare_Wid= 3,
    parameter IN_Wid  = 16 ,
    parameter OUT_Wid = 8
)(
    input                                   clk         ,

	input		[ARR_Len*IN_Wid-1:0] 	    in	        ,

	output		[Eshare_Wid-1:0] 	        exp_share   ,
    output      [ARR_Len*OUT_Wid-1:0]       out     
);

wire [(1 << Eshare_Wid) - 2:0] 	and_result          ;

genvar i;
generate 
    for (i = 0; i < ARR_Len; i = i + 1) begin:wire_assign
        wire [IN_Wid - 1:0]     in_g        = in[(i+1)*IN_Wid-1:i*IN_Wid];
        wire [IN_Wid - 2:0]     in_shift    = in_g[IN_Wid-2 : 0] << exp_share;
        assign out[(i+1)*OUT_Wid-1:i*OUT_Wid] = {in_g[IN_Wid - 1], in_shift[IN_Wid-2 -: OUT_Wid - 1]};
    end
endgenerate

assign and_result = wire_assign[ 0].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 1].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 2].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 3].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 4].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 5].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 6].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 7].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 8].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[ 9].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[10].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[11].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[12].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[13].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[14].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] |
                    wire_assign[15].in_g[IN_Wid-2 -: (1 << Eshare_Wid) - 1] ;
 
assign exp_share =  and_result[6] ? 3'd0 : 
                    and_result[5] ? 3'd1 : 
                    and_result[4] ? 3'd2 : 
                    and_result[3] ? 3'd3 : 
                    and_result[2] ? 3'd4 : 
                    and_result[1] ? 3'd5 : 
                    and_result[0] ? 3'd6 : 3'd7 ;

endmodule
